namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Search
{
    /// <summary>
    /// Elasticsearch搜索服务接口
    /// </summary>
    public interface IElasticsearchService
    {
        /// <summary>
        /// 检查连接状态
        /// </summary>
        Task<bool> IsHealthyAsync();

        /// <summary>
        /// 创建索引
        /// </summary>
        Task<ElasticsearchResult> CreateIndexAsync(string indexName, object? mapping = null);

        /// <summary>
        /// 删除索引
        /// </summary>
        Task<ElasticsearchResult> DeleteIndexAsync(string indexName);

        /// <summary>
        /// 检查索引是否存在
        /// </summary>
        Task<bool> IndexExistsAsync(string indexName);

        /// <summary>
        /// 添加文档
        /// </summary>
        Task<ElasticsearchResult> IndexDocumentAsync<T>(string indexName, string documentId, T document);

        /// <summary>
        /// 批量索引文档
        /// </summary>
        Task<ElasticsearchResult> BulkIndexAsync<T>(string indexName, IEnumerable<(string Id, T Document)> documents);

        /// <summary>
        /// 搜索文档
        /// </summary>
        Task<ElasticsearchSearchResult<T>> SearchAsync<T>(string indexName, object query, int from = 0, int size = 10);

        /// <summary>
        /// 删除文档
        /// </summary>
        Task<ElasticsearchResult> DeleteDocumentAsync(string indexName, string documentId);
    }

    /// <summary>
    /// Elasticsearch操作结果
    /// </summary>
    public class ElasticsearchResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; } = string.Empty;

        /// <summary>
        /// 数据
        /// </summary>
        public string? Data { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string? Error { get; set; }

        /// <summary>
        /// 时间戳
        /// </summary>
        public DateTime Timestamp { get; set; } = DateTime.UtcNow;
    }

    /// <summary>
    /// Elasticsearch搜索结果
    /// </summary>
    public class ElasticsearchSearchResult<T>
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 总结果数
        /// </summary>
        public long Total { get; set; }

        /// <summary>
        /// 文档列表
        /// </summary>
        public IEnumerable<ElasticsearchDocument<T>> Documents { get; set; } = new List<ElasticsearchDocument<T>>();

        /// <summary>
        /// 起始位置
        /// </summary>
        public int From { get; set; }

        /// <summary>
        /// 返回数量
        /// </summary>
        public int Size { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string? Error { get; set; }

        /// <summary>
        /// 时间戳
        /// </summary>
        public DateTime Timestamp { get; set; } = DateTime.UtcNow;

        /// <summary>
        /// 聚合结果
        /// </summary>
        public Dictionary<string, object> Aggregations { get; set; } = new();
    }

    /// <summary>
    /// Elasticsearch文档
    /// </summary>
    public class ElasticsearchDocument<T>
    {
        /// <summary>
        /// 文档ID
        /// </summary>
        public string Id { get; set; } = string.Empty;

        /// <summary>
        /// 文档源数据
        /// </summary>
        public T? Source { get; set; }

        /// <summary>
        /// 相关性评分
        /// </summary>
        public float Score { get; set; }

        /// <summary>
        /// 高亮结果
        /// </summary>
        public Dictionary<string, string[]> Highlight { get; set; } = new();

        /// <summary>
        /// 文档版本
        /// </summary>
        public long Version { get; set; }

        /// <summary>
        /// 索引名称
        /// </summary>
        public string Index { get; set; } = string.Empty;

        /// <summary>
        /// 文档类型
        /// </summary>
        public string Type { get; set; } = "_doc";
    }

    /// <summary>
    /// Elasticsearch配置选项
    /// </summary>
    public class ElasticsearchOptions
    {
        public const string SectionName = "Elasticsearch";

        /// <summary>
        /// 服务端点
        /// </summary>
        public string Endpoint { get; set; } = "http://localhost:9200";

        /// <summary>
        /// 用户名
        /// </summary>
        public string? Username { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
        public string? Password { get; set; }

        /// <summary>
        /// 超时时间（秒）
        /// </summary>
        public int TimeoutSeconds { get; set; } = 30;

        /// <summary>
        /// 默认分片数
        /// </summary>
        public int DefaultShards { get; set; } = 1;

        /// <summary>
        /// 默认副本数
        /// </summary>
        public int DefaultReplicas { get; set; } = 1;

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool Enabled { get; set; } = true;

        /// <summary>
        /// 索引前缀
        /// </summary>
        public string IndexPrefix { get; set; } = "cms_";

        /// <summary>
        /// 批量操作大小
        /// </summary>
        public int BulkSize { get; set; } = 1000;

        /// <summary>
        /// 最大重试次数
        /// </summary>
        public int MaxRetries { get; set; } = 3;

        /// <summary>
        /// 重试延迟（毫秒）
        /// </summary>
        public int RetryDelayMs { get; set; } = 1000;

        /// <summary>
        /// 是否启用调试日志
        /// </summary>
        public bool EnableDebugLogging { get; set; } = false;
    }

    /// <summary>
    /// 搜索查询构建器
    /// </summary>
    public static class ElasticsearchQueryBuilder
    {
        /// <summary>
        /// 匹配所有查询
        /// </summary>
        public static object MatchAll()
        {
            return new { match_all = new { } };
        }

        /// <summary>
        /// 多字段匹配查询
        /// </summary>
        public static object MultiMatch(string query, string[] fields, string type = "best_fields")
        {
            return new
            {
                multi_match = new
                {
                    query,
                    fields,
                    type,
                    fuzziness = "AUTO"
                }
            };
        }

        /// <summary>
        /// 词条查询
        /// </summary>
        public static object Term(string field, object value)
        {
            return new
            {
                term = new Dictionary<string, object> { [field] = value }
            };
        }

        /// <summary>
        /// 范围查询
        /// </summary>
        public static object Range(string field, object? gte = null, object? lte = null, object? gt = null, object? lt = null)
        {
            var range = new Dictionary<string, object>();
            if (gte != null) range["gte"] = gte;
            if (lte != null) range["lte"] = lte;
            if (gt != null) range["gt"] = gt;
            if (lt != null) range["lt"] = lt;

            return new
            {
                range = new Dictionary<string, object> { [field] = range }
            };
        }

        /// <summary>
        /// 布尔查询
        /// </summary>
        public static object Bool(
            object[]? must = null,
            object[]? mustNot = null,
            object[]? should = null,
            object[]? filter = null,
            int? minimumShouldMatch = null)
        {
            var boolQuery = new Dictionary<string, object>();
            
            if (must != null) boolQuery["must"] = must;
            if (mustNot != null) boolQuery["must_not"] = mustNot;
            if (should != null) boolQuery["should"] = should;
            if (filter != null) boolQuery["filter"] = filter;
            if (minimumShouldMatch != null) boolQuery["minimum_should_match"] = minimumShouldMatch;

            return new { @bool = boolQuery };
        }

        /// <summary>
        /// 通配符查询
        /// </summary>
        public static object Wildcard(string field, string value)
        {
            return new
            {
                wildcard = new Dictionary<string, object> { [field] = value }
            };
        }

        /// <summary>
        /// 前缀查询
        /// </summary>
        public static object Prefix(string field, string value)
        {
            return new
            {
                prefix = new Dictionary<string, object> { [field] = value }
            };
        }

        /// <summary>
        /// 存在字段查询
        /// </summary>
        public static object Exists(string field)
        {
            return new { exists = new { field } };
        }

        /// <summary>
        /// 词条集合查询
        /// </summary>
        public static object Terms(string field, object[] values)
        {
            return new
            {
                terms = new Dictionary<string, object> { [field] = values }
            };
        }
    }
}
